
/****************************************************************************/
/*Copyright (c) 2011, Florent DEVILLE.                                      */
/*All rights reserved.                                                      */
/*                                                                          */
/*Redistribution and use in source and binary forms, with or without        */
/*modification, are permitted provided that the following conditions        */
/*are met:                                                                  */
/*                                                                          */
/* - Redistributions of source code must retain the above copyright         */
/*notice, this list of conditions and the following disclaimer.             */
/* - Redistributions in binary form must reproduce the above                */
/*copyright notice, this list of conditions and the following               */
/*disclaimer in the documentation and/or other materials provided           */
/*with the distribution.                                                    */
/* - The names of its contributors cannot be used to endorse or promote     */
/*products derived from this software without specific prior written        */
/*permission.                                                               */
/* - The source code cannot be used for commercial purposes without         */ 
/*its contributors' permission.                                             */
/*                                                                          */
/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       */
/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT         */
/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS         */
/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE            */
/*COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,       */
/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,      */
/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;          */
/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER          */
/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT        */
/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN         */
/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE           */
/*POSSIBILITY OF SUCH DAMAGE.                                               */
/****************************************************************************/

#include "parameterWidget.h"

#include <QVBoxLayout>

#include "paramNoPrimitive.h"
#include "paramSpherePrimitive.h"
#include "paramBoxPrimitive.h"
#include "paramCylinderPrimitive.h"
#include "paramConePrimitive.h"
#include "paramTorusPrimitive.h"
#include "paramMeshPrimitive.h"
#include "paramVertexPrimitive.h"

#include "paramLightDirectional.h"
#include "paramLightPoint.h"
#include "paramLightSpot.h"

#include "paramCamera.h"

#include "Geometry.h"
#include "GUIILight.h"
#include "ICamera.h"

//constructor
parameterWidget::parameterWidget(QWidget* parent) : QWidget(parent), _currentWidget(0)
{
	_noPrimitive = new paramNoPrimitive();
	_spherePrimitive = new paramSpherePrimitive();
	_boxPrimitive = new paramBoxPrimitive();
	_cylinderPrimitive = new paramCylinderPrimitive();
	_conePrimitive = new paramConePrimitive();
	_torusPrimitive = new paramTorusPrimitive();
	_meshPrimitive = new paramMeshPrimitive();
	_vertexPrimitive = new paramVertexPrimitive();

	_directionalLight = new paramLightDirectional();
	_pointLight = new paramLightPoint();
	_spotLight = new paramLightSpot();

	_camera = new paramCamera();

	_layout = new QVBoxLayout(this);
	_layout->addWidget(_noPrimitive);
	_layout->addWidget(_spherePrimitive);
	_layout->addWidget(_boxPrimitive);
	_layout->addWidget(_cylinderPrimitive);
	_layout->addWidget(_conePrimitive);
	_layout->addWidget(_torusPrimitive);
	_layout->addWidget(_meshPrimitive);
	_layout->addWidget(_vertexPrimitive);
	_layout->addWidget(_directionalLight);
	_layout->addWidget(_pointLight);
	_layout->addWidget(_spotLight);
	_layout->addWidget(_camera);

	setLayout(_layout);

	//show no primitive
	hideAll();
	_noPrimitive->show();
}

//destructor
parameterWidget::~parameterWidget()
{}

//slot changing the primitive displayed
void parameterWidget::changePrimitive(Geometry* p)
{
	//hide all the widgets
	hideAll();

	//no primitive
	if (p == 0)
	{
		_currentWidget = 0;
		_noPrimitive->show();
		return;
	}

	//a primitive is selected
	switch(p->getType())
	{
		case GT_SPHERE:
			_spherePrimitive->fillWidgets(p);
			_spherePrimitive->show();
			_currentWidget = _spherePrimitive;
			break;
		case GT_BOX:
			_boxPrimitive->fillWidgets(p);
			_boxPrimitive->show();
			_currentWidget = _boxPrimitive;
			break;
		case GT_CYLINDER:
			_cylinderPrimitive->fillWidgets(p);
			_cylinderPrimitive->show();
			_currentWidget = _cylinderPrimitive;
			break;
		case GT_CONE:
			_conePrimitive->fillWidgets(p);
			_conePrimitive->show();
			_currentWidget = _conePrimitive;
			break;
		case GT_TORUS:
			_torusPrimitive->fillWidgets(p);
			_torusPrimitive->show();
			_currentWidget = _torusPrimitive;
			break;
		case GT_MESH:
			_meshPrimitive->fillWidgets(p);
			_meshPrimitive->show();
			_currentWidget = _meshPrimitive;
			break;
		case GT_VERTEX:
			_vertexPrimitive->fillWidgets(p);
			_vertexPrimitive->show();
			_currentWidget = _vertexPrimitive;
			break;
		default:
			_noPrimitive->show();
			break;
	}
}

//set the right layout for lights
void parameterWidget::changeLight(GUIILight* l)
{
	//hide all the widgets
	hideAll();

	//no light
	if (l == 0)
	{
		_currentWidget = 0;
		_noPrimitive->show();
		return;
	}

	//a light is selected
	switch(l->getType())
	{
		case LT_DIRECTIONAL:
		case LT_DIRECTIONAL_AT:
			_directionalLight->fillWidgets(l);
			_directionalLight->show();
			_currentWidget = _directionalLight;
			break;
		case LT_POINT:
			_pointLight->fillWidgets(l);
			_pointLight->show();
			_currentWidget = _pointLight;
			break;
		case LT_SPOT:
		case LT_SPOT_AT:
			_spotLight->fillWidgets(l);
			_spotLight->show();
			_currentWidget = _spotLight;
			break;
		default:
			_noPrimitive->show();
			break;
	}
}

//set the right layout for camera
void parameterWidget::changeCamera(ICamera* c)
{
	//hide all the widgets
	hideAll();

	//no light
	if (c == 0)
	{
		_currentWidget = 0;
		_noPrimitive->show();
		return;
	}

	if(c->getMovableType() != MT_CAMERA)
	{
		_currentWidget = 0;
		_noPrimitive->show();
		return;
	}

	_camera->fillWidgets(c);
	_camera->show();
	_currentWidget = _camera;
}


//set the translate info
void parameterWidget::setTranslate(float x, float y, float z)
{
	if(_currentWidget == 0)
		return;

	_currentWidget->setPosition(x, y, z);
}

//set the rotation info
void parameterWidget::setRotate(float x, float y, float z)
{
	if(_currentWidget == 0)
		return;

	_currentWidget->setRotation(x, y, z);
}

//set the scale info
void parameterWidget::setScale(float x, float y, float z)
{
	if(_currentWidget == 0)
		return;

	_currentWidget->setScale(x, y ,z);
}

//hide all the widgets
void parameterWidget::hideAll()
{
	_noPrimitive->hide();
	_spherePrimitive->hide();
	_boxPrimitive->hide();
	_cylinderPrimitive->hide();
	_conePrimitive->hide();
	_torusPrimitive->hide();
	_meshPrimitive->hide();
	_vertexPrimitive->hide();
	_directionalLight->hide();
	_pointLight->hide();
	_spotLight->hide();
	_camera->hide();
}